package com.shangxia.spr.frame;

import com.shangxia.spr.mapper.dao.Attribute;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.Assert;

import javax.annotation.PostConstruct;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhouya38158
 * @date 2021/11/18 14:36
 * @apiNote 属性 VO
 */
public interface AttributeI {
    /**
     * 填充属性值
     * checkBaseAttributeEnum 方法保证安全
     *
     * @param attribute 属性来源
     * @param field     属性字段
     */
    default void putField(Attribute attribute, String field) {
        BeanWrapper tbw = new BeanWrapperImpl(this);
        if (!BigDecimal.class.equals(tbw.getPropertyType(field))) {
            return;
        }
        ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
        Logger logger = loggerFactory.getLogger("ROOT");
        logger.debug("this={}", this);
        logger.debug("attribute={}", attribute);
        logger.debug("field={}", field);
        BigDecimal value = attribute.getAttributeValue().multiply(attribute.getAttributePctValue().add(new BigDecimal(100)))
                .divide(new BigDecimal(100), 0, BigDecimal.ROUND_HALF_UP)
                .add(attribute.getAttributeAddValue());
        tbw.setPropertyValue(field, value);
        logger.debug("this={}", this);
    }

    /**
     * 校验属性种类与枚举是否匹配 ,同时初始化
     */
    @PostConstruct
    default void checkAttributeEnum() {
        List<String> list = new ArrayList<>();
        for (AttributeEnumI value : getAttributeEnumI()) {
            list.add(value.name());
        }
        BeanWrapper bw = new BeanWrapperImpl(this);
        for (PropertyDescriptor pd : bw.getPropertyDescriptors()) {
            list.remove(pd.getDisplayName());
        }
        Assert.isTrue(1 == list.size(), "BaseAttributeVO与BaseAttributeEnum 属性一致");
        for (Field field : this.getClass().getDeclaredFields()) {
            if (field.getType().equals(BigDecimal.class)) {
                bw.setPropertyValue(field.getName(), new BigDecimal(1));
            }
        }
    }

    /**
     * 获取本类型的属性字段
     *
     * @return 本类型的属性字段数组
     */
    AttributeEnumI[] getAttributeEnumI();

    /**
     * 获取子AttributeVO
     *
     * @return 子AttributeVO
     */
    AttributeI getAttributeImpl();

}
